

#include "mcu_api.h"
#include "error.h"


namespace mcu {


const string kEventQueueCreate = "EventQueueCreate";
const string kEventQueueDelete = "EventQueueDelete";
const string kCreateConference = "CreateConference";
const string kDeleteConference = "DeleteConference";
const string kCreateMosaic = "CreateMosaic";
const string kDeleteMosaic = "DeleteMosaic";
const string kCreateSidebar = "CreateSidebar";
const string kDeleteSidebar = "DeleteSidebar";
const string kCreateParticipant = "CreateParticipant";
const string kDeleteParticipant = "DeleteParticipant";
const string kStartPublishing = "StartPublishing";
const string kStopPublishing = "StopPublishing";
const string kStartReceiving = "StartReceiving";
const string kStopReceiving = "StopReceiving";

xmlrpc_c::clientSimple XmlRpc::_xmlrpc;

error XmlRpc::CreateEventQueue(string& url, int* pID) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kEventQueueCreate,&result);

  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%d\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }

  auto value = xmlrpc_c::value_array(values["returnVal"]).cvalue();
  auto queueID = xmlrpc_c::value_int(value[0]);
  *pID = queueID;
  if(queueID == 0) {
    return ERR_XMLRPC_VALUE;
  }
  return ERR_NONE;
}

error XmlRpc::DeleteEventQueue(string& url, int id) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kEventQueueDelete,"i",&result, id);

  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  return ERR_NONE;
}


error XmlRpc::CreateConference(string& url, string& tags, 
      int vad, int rate,int queueID, int* pID) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kCreateConference,"siii",&result, tags.c_str(), vad, rate,queueID);
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  auto value = xmlrpc_c::value_array(values["returnVal"]).cvalue();
  auto confID = xmlrpc_c::value_int(value[0]);
  if(confID == 0) {
    return ERR_XMLRPC_VALUE;
  }
  *pID = confID;
  return ERR_NONE;
}

error XmlRpc::DeleteConference(string& url, int confID) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kEventQueueDelete,"i",&result,confID);
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  return ERR_NONE;
}


error XmlRpc::CreateMosaic(string& url, int confID, int comp,
       int size,int* pID) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kCreateMosaic,"iii",&result, confID, comp, size);
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  auto value = xmlrpc_c::value_array(values["returnVal"]).cvalue();
  auto mosaicID = xmlrpc_c::value_int(value[0]);
  if(mosaicID == 0) {
    return ERR_XMLRPC_VALUE;
  }
  *pID = mosaicID;
  return ERR_NONE;
}

error XmlRpc::DeleteMosaic(string& url, int confID, int mosaicID) {
   xmlrpc_c::value result;
  _xmlrpc.call(url, kDeleteMosaic,"ii",&result,confID,mosaicID);
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  return ERR_NONE;
}


error XmlRpc::CreateSidebar(string& url, int confID, int* pID) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kCreateSidebar,"i",&result, confID);
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  auto value = xmlrpc_c::value_array(values["returnVal"]).cvalue();
  auto sidebarID = xmlrpc_c::value_int(value[0]);
  if(  sidebarID == 0) {
    return  ERR_XMLRPC_VALUE;
  }
  *pID  = sidebarID;
  return ERR_NONE;
}

error XmlRpc::DeleteSidebar(string& url, int confID, int sidebarID) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kDeleteSidebar,"ii",&result,confID,sidebarID);
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  return ERR_NONE;
};


error XmlRpc::CreateParticipant(string& url,int confID, int mosaicID,
               int sidebarID, string& sname, string& token, int type, int* pID) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kCreateParticipant,"isiii",&result, confID, sname.c_str(),
    type, mosaicID, sidebarID);
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  auto value = xmlrpc_c::value_array(values["returnVal"]).cvalue();
  auto partID = xmlrpc_c::value_int(value[0]);
  if( partID ==0 ) {
    return ERR_XMLRPC_VALUE;
  }
  *pID = partID;
  return ERR_NONE;
}

error XmlRpc::DeleteParticipant(string& url,int confID, int partID) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kDeleteParticipant,"ii", &result, confID, partID);
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  return ERR_NONE;
}



error XmlRpc::StartPublishing(string& url, int confID, string& rtmpServer,
               int port, string& app, string& stream, int* pID) {
   xmlrpc_c::value result;
  _xmlrpc.call(url, kStartPublishing,"isiss",&result, confID, rtmpServer.c_str(),
    port, app.c_str(), stream.c_str());
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  auto value = xmlrpc_c::value_array(values["returnVal"]).cvalue();
  auto publishingID = xmlrpc_c::value_int(value[0]);
  if( publishingID ==0 ) {
    return ERR_XMLRPC_VALUE;
  }
  *pID = publishingID;
  return ERR_NONE;
}

error XmlRpc::StopPublishing(string& url, int confID, int id) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kStopPublishing,"ii", &result, confID, id);
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  return ERR_NONE;
}


error XmlRpc::StartReceiving(string& url, int confID, int partID,
              int media, RtpMap& rtpMap, RtpMap& aptMap, int* pPort) {
  xmlrpc_c::value result;
  xmlrpc_env env;
  xmlrpc_env_init(&env);
  auto rtp = xmlrpc_struct_new(&env);
  auto codec1 = xmlrpc_int_new(&env, rtpMap.codec);
  xmlrpc_struct_set_value(&env,rtp, rtpMap.type.c_str(),codec1);
  auto apt = xmlrpc_struct_new(&env);
  auto codec2 = xmlrpc_int_new(&env, aptMap.codec);
  xmlrpc_struct_set_value(&env,apt, aptMap.type.c_str(),codec2);

  _xmlrpc.call(url, kStartReceiving,"iiiSS", &result, confID, partID,
      media, rtp, apt);

  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  auto value = xmlrpc_c::value_array(values["returnVal"]).cvalue();
  auto port = xmlrpc_c::value_int(value[0]);
  if(port == 0) {
    return ERR_XMLRPC_VALUE;
  }
  *pPort = port;
  return ERR_NONE;
}

error XmlRpc::StopReceiving(string& url, int confID, int partID, int media) {
  xmlrpc_c::value result;
  _xmlrpc.call(url, kStopReceiving,"iii", &result, confID, partID, media);
  auto values = xmlrpc_c::value_struct(result).cvalue();
  auto code = xmlrpc_c::value_int(values["returnCode"]);
  if(code != 1) {
    printf("%s code:%ld\n", __FUNCTION__, code);
    return ERR_XMLRPC;
  }
  return ERR_NONE;
}

} // end of namespace
